package com.nanhai.buddhist.college.module.study.service.attendancemanagementlog;

import cn.hutool.core.collection.CollectionUtil;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.module.study.controller.admin.attendancemanagement.vo.AttendanceManagementPageReqVO;
import com.nanhai.buddhist.college.module.study.dal.dataobject.attendanceleavereason.AttendanceLeaveReasonDO;
import com.nanhai.buddhist.college.module.study.dal.dataobject.attendancemanagement.AttendanceManagementDO;
import com.nanhai.buddhist.college.module.study.service.attendanceleavereason.AttendanceLeaveReasonService;
import com.nanhai.buddhist.college.module.study.service.attendancemanagement.AttendanceManagementService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import com.nanhai.buddhist.college.module.study.controller.admin.attendancemanagementlog.vo.*;
import com.nanhai.buddhist.college.module.study.dal.dataobject.attendancemanagementlog.AttendanceManagementLogDO;
import com.nanhai.buddhist.college.framework.common.pojo.PageResult;

import com.nanhai.buddhist.college.module.study.convert.attendancemanagementlog.AttendanceManagementLogConvert;
import com.nanhai.buddhist.college.module.study.dal.mysql.attendancemanagementlog.AttendanceManagementLogMapper;

import static com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.nanhai.buddhist.college.module.study.enums.ErrorCodeConstants.*;

/**
 * 请假审核记录 Service 实现类
 *
 * @author AKai
 */
@Service
@Validated
public class AttendanceManagementLogServiceImpl implements AttendanceManagementLogService {

    @Resource
    private AttendanceManagementLogMapper attendanceManagementLogMapper;

    @Resource
    private AttendanceManagementService attendanceManagementService;

    @Resource
    private AttendanceLeaveReasonService attendanceLeaveReasonService;


    @Override
    public String createAttendanceManagementLog(AttendanceManagementLogCreateReqVO createReqVO) {
        // 插入
        AttendanceManagementLogDO attendanceManagementLog = AttendanceManagementLogConvert.INSTANCE.convert(createReqVO);
        attendanceManagementLogMapper.insert(attendanceManagementLog);
        // 返回
        return attendanceManagementLog.getId();
    }

    @Override
    public void updateAttendanceManagementLog(AttendanceManagementLogUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateAttendanceManagementLogExists(updateReqVO.getId());
        // 更新
        AttendanceManagementLogDO updateObj = AttendanceManagementLogConvert.INSTANCE.convert(updateReqVO);
        attendanceManagementLogMapper.updateById(updateObj);
    }

    @Override
    public void deleteAttendanceManagementLog(String id) {
        // 校验存在
        this.validateAttendanceManagementLogExists(id);
        // 删除
        attendanceManagementLogMapper.deleteById(id);
    }

    private void validateAttendanceManagementLogExists(String id) {
        if (attendanceManagementLogMapper.selectById(id) == null) {
            throw exception(ATTENDANCE_MANAGEMENT_LOG_NOT_EXISTS);
        }
    }

    @Override
    public AttendanceManagementLogDO getAttendanceManagementLog(String id) {
        return attendanceManagementLogMapper.selectById(id);
    }

    @Override
    public List<AttendanceManagementLogDO> getAttendanceManagementLogList(Collection<String> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : attendanceManagementLogMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ManagementLogResVO> getAttendanceManagementLogPage(AttendanceManagementLogPageReqVO pageReqVO) {
        PageResult<AttendanceManagementLogDO> selectPage = attendanceManagementLogMapper.selectPage(pageReqVO);
        List<AttendanceManagementLogDO> list = selectPage.getList();
        PageResult<ManagementLogResVO> resPage = new PageResult<>();
        resPage.setTotal(selectPage.getTotal());
        if (CollectionUtil.isEmpty(list)) {
            return resPage;
        }
        // 设置请假天数，事由，请假提交时间
        List<ManagementLogResVO> resVOList = setResVO(list);
        resPage.setList(resVOList);
        return resPage;
    }

    @NotNull
    private List<ManagementLogResVO> setResVO(List<AttendanceManagementLogDO> list) {
        List<ManagementLogResVO> resVOList = new ArrayList<>(list.size());
        if (CollectionUtil.isEmpty(list)) {
            return resVOList;
        }
        // 查询列表中的所有请假记录
        List<String> managementIds = list.stream().map(AttendanceManagementLogDO::getManagementId).distinct().collect(Collectors.toList());
        List<AttendanceManagementDO> managementList = attendanceManagementService.getAttendanceManagementList(managementIds);

        // 查询请假中的事由（请假类型）
        List<AttendanceLeaveReasonDO> leaveReasonList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(managementList)) {
            List<String> reasonIds = managementList.stream().map(AttendanceManagementDO::getReasonId).distinct().collect(Collectors.toList());
            leaveReasonList = attendanceLeaveReasonService.getAttendanceLeaveReasonList(reasonIds);
        }

        final List<AttendanceLeaveReasonDO> finalLeaveReasonList = leaveReasonList;
        list.forEach(item -> {
            ManagementLogResVO managementLogResVO = new ManagementLogResVO();
            BeanUtils.copyProperties(item, managementLogResVO);
            if (CollectionUtil.isNotEmpty(managementList)) {
                List<AttendanceManagementDO> collect = managementList.stream().filter(s -> s.getId().equals(item.getManagementId())).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(collect)) {
                    AttendanceManagementDO managementDO = collect.get(0);
                    managementLogResVO.setSubmitTime(managementDO.getCreateTime());
                    managementLogResVO.setLeaveDays(managementDO.getLeaveDays());
                    // 根据请假记录，获取请假事由
                    setReason(finalLeaveReasonList, managementLogResVO, managementDO);

                }
            }

            resVOList.add(managementLogResVO);

        });
        return resVOList;
    }

    private void setReason(List<AttendanceLeaveReasonDO> finalLeaveReasonList, ManagementLogResVO managementLogResVO, AttendanceManagementDO attendanceManagementDO) {
        if (CollectionUtil.isNotEmpty(finalLeaveReasonList)) {
            List<AttendanceLeaveReasonDO> reasonDOS = finalLeaveReasonList.stream().filter(s -> s.getId().equals(attendanceManagementDO.getReasonId())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(reasonDOS)) {
                final AttendanceLeaveReasonDO reasonDO = reasonDOS.get(0);
                managementLogResVO.setLeaveReason(reasonDO.getLeaveReason());
            }
        }
    }

    @Override
    public List<AttendanceManagementLogDO> getAttendanceManagementLogList(AttendanceManagementLogExportReqVO exportReqVO) {
        return attendanceManagementLogMapper.selectList(exportReqVO);
    }


}
